package com.keyue.isolate.handler;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;

import com.keyue.common.constant.Constant;
import com.keyue.isolate.constant.DataIsolateConstants;
import com.keyue.isolate.context.DataIsolateValue;
import com.keyue.isolate.context.IsolateTableConfigVO;
import com.keyue.isolate.enums.DataIsolateValueTypeEnum;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.IsNullExpression;
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.util.cnfexpression.MultiOrExpression;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class InDataIsolateExpStragegy extends DataIsolateExpStragegy {

    public static final DataIsolateExpStragegy SINGLE_INSTANCE = new InDataIsolateExpStragegy();

    Expression parse(DataIsolateValue dataIsolateValue, String prefix, IsolateTableConfigVO configVO){

        List<String> codes = getCodes(dataIsolateValue, configVO.getDataIsolateColumnName());
        if (CollectionUtils.isEmpty(codes) || codes.stream().anyMatch(x -> x.equalsIgnoreCase(Constant.ALL))) {
            return null;
        }
        boolean hasNullValue = codes.removeIf(DataIsolateConstants.NULL_VALUE_CODE::equalsIgnoreCase);

        if (DataIsolateValueTypeEnum.CARRIER_CODES.getCode().equals(configVO.getDataIsolateColumnName())) {
            // 兼容为空字符串
            if (hasNullValue) {
                codes.add("");
            }
        }
        List<Expression> finalExpressions = new ArrayList<>(2);
        Column column = new Column(prefix + configVO.getTableColumnName());

        if (CollectionUtils.isNotEmpty(codes)){
            InExpression inExpression = new InExpression();
            inExpression.setLeftExpression(column);
            inExpression.setRightExpression(new ParenthesedExpressionList<>(codes.stream().map(StringValue::new).collect(Collectors.toList())));
            finalExpressions.add(inExpression);
        }

        if (hasNullValue) {
            //存在“空值编码”添加 column is null 表达式
            IsNullExpression isNullExpression = new IsNullExpression();
            isNullExpression.setLeftExpression(column);
            finalExpressions.add(isNullExpression);
        }

        return new MultiOrExpression(finalExpressions);
    }

}
